/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
extern uint8_t receive_buff[255];                                                  //声明外部变量
extern uint16_t  RecLen;
uint8_t  DeviceStatus[7] = {0,0,0,0,0,0,0};
uint8_t DeviceSetCmd[7] = {0,0,0,0,0,0,0};
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId defaultTaskHandle;
osThreadId UartRecHandle;
osThreadId RadiumHandle;
osThreadId DustHandle;
osSemaphoreId UartRecSemHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
uint8_t  Crc8(uint8_t *buff,uint16_t len){
    uint8_t CheckSum = 0;
    for(int i = 0;i<len;i++){
        CheckSum+= buff[i];
    }
    return (CheckSum & 0xff);
}

void ReportWorkStatus(uint8_t Device){
    static uint8_t Buff[16];
    Buff[0] = 0xFA;
    Buff[1] = 0XC1;
    Buff[2] = sizeof (Buff);
    Buff[3] = 0x01;
    Buff[4] = Device;
    Buff[15] = Crc8(Buff,sizeof (Buff)-1);

    HAL_UART_Transmit(&huart2,Buff,sizeof (Buff),0xffff);
}

void ReportCheckWorkStatus(uint8_t Device,uint8_t Status){
    static uint8_t Buff[16];
    Buff[0] = 0xFA;
    Buff[1] = 0XC2;
    Buff[2] = sizeof (Buff);
    Buff[3] = 0x01;
    Buff[4] = Device;
    Buff[5] = Status;
    Buff[15] = Crc8(Buff,sizeof (Buff)-1);

    HAL_UART_Transmit(&huart2,Buff,sizeof (Buff),0xffff);
}
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const * argument);
void UartRecEntry(void const * argument);
void Radium_Task(void const * argument);
void Dust_Task(void const * argument);

extern void MX_USB_DEVICE_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* Create the semaphores(s) */
  /* definition and creation of UartRecSem */
  osSemaphoreDef(UartRecSem);
  UartRecSemHandle = osSemaphoreCreate(osSemaphore(UartRecSem), 1);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of UartRec */
  osThreadDef(UartRec, UartRecEntry, osPriorityNormal, 0, 256);
  UartRecHandle = osThreadCreate(osThread(UartRec), NULL);

  /* definition and creation of Radium */
  osThreadDef(Radium, Radium_Task, osPriorityNormal, 0, 128);
  RadiumHandle = osThreadCreate(osThread(Radium), NULL);

  /* definition and creation of Dust */
  osThreadDef(Dust, Dust_Task, osPriorityNormal, 0, 128);
  DustHandle = osThreadCreate(osThread(Dust), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
  /* init code for USB_DEVICE */
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  static uint16_t cnt = 0;
    //HAL_UART_Receive_DMA(&huart2, (uint8_t*)receive_buff, 255);                    //重启�????????始DMA传输 每次255字节数据

    for(;;)
  {
      if(cnt++>=30){
          cnt = 0;
          HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
        //  usb_printf("LeiDiaoTest\n");
      }
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_UartRecEntry */
/**
* @brief Function implementing the UartRec thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_UartRecEntry */
void UartRecEntry(void const * argument)
{
  /* USER CODE BEGIN UartRecEntry */
  /* Infinite loop */
  static uint8_t  DeviceName = Device_Null;
  for(;;)
  {
      if(osSemaphoreWait(UartRecSemHandle,10) == osOK){
          if(receive_buff[0] == 0xFA && receive_buff[RecLen-1] == Crc8(receive_buff,RecLen - 1)){
              DeviceName = receive_buff[4];

              if(receive_buff[1] == 0xC1){
                  if(DeviceName == Device_Null){
                      DeviceSetCmd[Device_Radium] = 1;
                      DeviceSetCmd[Device_Dust] = 1;
                  }
                  else if(DeviceName == Device_Radium){
                      DeviceSetCmd[Device_Radium] = 1;
                      ReportWorkStatus(Device_Radium);
                  }
                  else if(DeviceName == Device_Dust){
                      DeviceSetCmd[Device_Dust] = 1;
                      ReportWorkStatus(Device_Dust);
                  }
              }
              else if(receive_buff[1] == 0xc2){
                  if(DeviceName == Device_Null){

                  }
                  else if(DeviceName == Device_Radium){

                      ReportCheckWorkStatus(Device_Radium,DeviceStatus[Device_Radium]);
                  }
                  else if(DeviceName == Device_Dust){
                      ReportCheckWorkStatus(Device_Radium,DeviceStatus[Device_Dust]);
                  }
              }
          }
          memset(receive_buff,0,sizeof(receive_buff));
          RecLen = 0;

      }
    osDelay(1);
  }
  /* USER CODE END UartRecEntry */
}

/* USER CODE BEGIN Header_Radium_Task */
/**
* @brief Function implementing the Radium thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Radium_Task */
void Radium_Task(void const * argument)
{
  /* USER CODE BEGIN Radium_Task */
  /* Infinite loop */
  static uint8_t flag = 0;
  static uint16_t overcnt = 0,startcnt = 0;
  for(;;)
  {
      if(DeviceSetCmd[Device_Radium] == 1){
          DeviceStatus[Device_Radium] = 2;
          flag = 0;
          if(++startcnt>=10){
              startcnt = 0;
              Radium_L;
              DeviceSetCmd[Device_Radium] = 0;
          }else {
              Radium_H;
          }
      }
      else {
          startcnt = 0;
          Radium_L;
      }
      if(flag == 1){
          if(++overcnt>=1000){
              overcnt = 0;
              DeviceStatus[Device_Radium] = 1;
              flag = 0;
          }
      }else if(flag == 0){
          overcnt = 0;

      }
    osDelay(1);
  }
  /* USER CODE END Radium_Task */
}

/* USER CODE BEGIN Header_Dust_Task */
/**
* @brief Function implementing the Dust thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Dust_Task */
void Dust_Task(void const * argument)
{
  /* USER CODE BEGIN Dust_Task */
  /* Infinite loop */
    static uint8_t flag = 0;
    static uint16_t overcnt = 0,startcnt = 0;
  for(;;)
  {
      if(DeviceSetCmd[Device_Dust] == 1){
          DeviceStatus[Device_Dust] = 2;
          flag = 0;
          if(++startcnt>=1000){
              startcnt = 0;
              Dust_L;
              DeviceSetCmd[Device_Dust] = 0;
          }else {
              Dust_H;
          }
      }
      else {
          startcnt = 0;
          Dust_L;
      }
      if(flag == 1){
          if(++overcnt>=1000){
              overcnt = 0;
              DeviceStatus[Device_Dust] = 1;
              flag = 0;
          }
      }else if(flag == 0){
          overcnt = 0;

      }
    osDelay(1);
  }
  /* USER CODE END Dust_Task */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

